﻿using System;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Framework.Serialization;
using IQIGame.Onigao.Logic;
using LFloatMath.Math;

namespace IQIGame.Onigao.GamePlay
{
    public class DamageResponse : IReusableClassWithFree, ISerializeCustomPOD
    {
        public long attacker;
        public long defender;

        public int configID;

        public bool dodge;
        public bool crit;

        public LFloat baseDamage;
        public int finalDamage;
        public int realDamage; // 伤害扣血量，剔除了护盾与溢出伤害

        public EDamageFrom damageFrom = EDamageFrom.None;
        public EDamageType damageType = EDamageType.Default;
        public EBackstabType backstab = EBackstabType.Front;

        public uint MaxStore => 10;

        public void OnReset()
        {
            this.finalDamage = 0;
            this.configID = 0;
            this.attacker = 0;
            this.defender = 0;
            this.dodge = false;
            this.crit = false;
            this.baseDamage = LFloat.zero;
            this.finalDamage = 0;
            this.damageFrom = EDamageFrom.None;
            this.damageType = EDamageType.Default;
            this.backstab = EBackstabType.Front;
            this.realDamage = 0;
        }

        public void Free()
        {
            ClassPool.Put(this);
        }

        public void Serialize(SOutputStream _buf)
        {
            _buf.Write_long(this.attacker);
            _buf.Write_long(this.defender);
            _buf.Write_int(this.configID);
            _buf.Write_boolean(this.dodge);
            _buf.Write_boolean(this.crit);
            _buf.Write_long(this.baseDamage._val);
            _buf.Write_int(this.finalDamage);
            _buf.Write_int((int)this.damageFrom);
            _buf.Write_int((int)this.damageType);
            _buf.Write_int((int)this.backstab);
            _buf.Write_int(this.realDamage);
        }

        public void DeSerialize(SInputStream _buf)
        {
            this.attacker = _buf.Read_long();
            this.defender = _buf.Read_long();
            this.configID = _buf.Read_int();
            this.dodge = _buf.Read_boolean();
            this.crit = _buf.Read_boolean();
            this.baseDamage = new LFloat(true, (long)_buf.Read_long());
            this.finalDamage = _buf.Read_int();
            this.damageFrom = (EDamageFrom)_buf.Read_int();
            this.damageType = (EDamageType)_buf.Read_int();
            this.backstab = (EBackstabType)_buf.Read_int();
            this.realDamage = _buf.Read_int();
        }

#if UNITY_EDITOR
        public override string ToString()
        {
            return $"{this.finalDamage}({this.realDamage})[{this.attacker}->{this.defender}({(EDamageType)this.damageType})] : 基础伤害[{this.baseDamage}], 闪避[{this.dodge}], 暴击[{this.crit}], 来源[{(EDamageFrom)this.damageFrom}({this.configID})], 背刺[{this.backstab}]";
        }
#endif
    }

    public class CureResponse : IReusableClassWithFree, ISerializeCustomPOD
    {
        public long attacker;
        public long defender;

        public LFloat baseCure;
        public int finalCure;
        public int realCure;

        public uint MaxStore => 10;

        public void OnReset()
        {
            this.attacker = 0;
            this.defender = 0;

            this.baseCure = LFloat.zero;
            this.finalCure = 0;
            this.realCure = 0;
        }


        public void Serialize(SOutputStream _buf)
        {
            _buf.Write_long(this.attacker);
            _buf.Write_long(this.defender);
            _buf.Write_long(this.baseCure._val);
            _buf.Write_int(this.finalCure);
        }

        public void DeSerialize(SInputStream _buf)
        {
            this.attacker = _buf.Read_long();
            this.defender = _buf.Read_long();
            this.baseCure = new LFloat(true, (long)_buf.Read_long());
            this.finalCure = _buf.Read_int();
        }

        public void Free()
        {
            ClassPool.Put(this);
        }
        
#if UNITY_EDITOR
        public override string ToString()
        {
            return $"<color=\"green\">[治疗]{this.realCure}[{this.attacker}->{this.defender}] : 结算治疗[{this.finalCure}] 基础伤害[{this.baseCure}]]</color>";
        }
#endif
    }

    [Flags]
    public enum EDamageFrom
    {
        None = 0,
        Skill = 1 << 1,
        CommonAtk = 1 << 2,
        Buff = 1 << 3
    }
    
    public enum EBackstabType
    {
        Front,
        Flank,
        Back,
    }
    
}